package com.nfit.shopweb.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.nfit.shopcommon.utils.MenuUtil;
import com.nfit.shopcommon.utils.ThreadLocalUtil;
import com.nfit.shopmodel.entity.system.SysMenu;
import com.nfit.shopmodel.entity.system.SysUser;
import com.nfit.shopmodel.vo.system.SysMenuVo;
import com.nfit.shopweb.mapper.SysMenuMapper;
import com.nfit.shopweb.mapper.SysRoleMenuMapper;
import com.nfit.shopweb.service.SysMenuService;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedList;
import java.util.List;

import static com.nfit.shopmodel.vo.common.AuthConst.THREADLOCAL_API_USER;

/**
 * ClassName:SysMenuServiceImpl
 * Package:com.nfit.shopweb.service.impl
 * Description
 *
 * @Author L
 * @Create 2024/11/19 19:26
 */
@Schema(description = "菜单业务实现")
@Service
@Slf4j
public class SysMenuServiceImpl implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    /**
     * 实现思路：
     * 第一步：查询全部的菜单数据,判断是否为null,为null直接返回null.
     * 第二步：MenuUtil.buildTree(list); 封装一个菜单工具类,构建树型菜单,list:所有菜单数据
     *第三步： 返回构建好的树形菜单
     */
    @Override
    public List<SysMenu> menuList() {
        //查询所有菜单数据
        List<SysMenu> list = sysMenuMapper.menuList();
        //判断集合是否为空
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        List<SysMenu> treeMenuList = MenuUtil.buildTree(list);
        return treeMenuList;
    }

    /**
     *查询用户的所对应菜单列表
     * 实现思路：第一步从ThreadLocalUtil工具类中获取登入的用户的id
     *  第二步： 根据用户的id查询
     */
    @Override
    public List<SysMenuVo> findUserMenu() {
        //第一步：从threadLocalUtil 工具类中获取登入的用户的id
        SysUser sysUser = ThreadLocalUtil.get(THREADLOCAL_API_USER);
        Long userId = sysUser.getId();
        log.info("查询用户的所对应菜单列表获取到userId:{}",userId);
        //根据用户id查询数据
        List<SysMenu> sysMenuList = sysMenuMapper.findUserIdMenu(userId);

        //构建好的树形菜单
        List<SysMenu> listTree = MenuUtil.buildTree(sysMenuList);
        //
        List<SysMenuVo> list = buildMenuList(listTree);
        return list;
    }

    /**
     * 添加菜单
     * @param sysMenu 菜单实体
     */
    @Override
    @Transactional
    public void save(SysMenu sysMenu) {
        //添加菜单
        sysMenuMapper.save(sysMenu);

        // 新添加一个菜单，那么此时就需要将该菜单所对应的父级菜单设置为半开
        updateMenuParentIdIsHalf(sysMenu);

    }

    /**
     * bug:
     * 为角色分配菜单，全部选中，比如系统管理全部选中,在系统管理下面添加新的子菜单,点击分配角色，新添加的子菜单默认也会选中
     *
     * 实现思路：
     *  第一步：根据前端传来的SysMenu对象,如果 ParentId = 0 表示是父级菜单
     *  第二步：判断isParentMenu !=null ,根据菜单id修改当前的菜单isHaIf = 1 为半开
     *
     * @param sysMenu 菜单
     */
    private void updateMenuParentIdIsHalf(SysMenu sysMenu) {

        //查看是否存在父节点
        SysMenu isParentMenu = sysMenuMapper.selectById(sysMenu.getParentId());

        //判断不为null
        if (isParentMenu != null) {
            // 将该id的菜单设置为半开
            sysRoleMenuMapper.updateMenuParentIdIsHalf(isParentMenu.getId());
            // 递归调用
            updateMenuParentIdIsHalf(isParentMenu);
        }
    }

    /**
     * 修改菜单
     * 根据实体里面专递的id作为条件
     * @param sysMenu 菜单实体
     */
    @Override
    public void update(SysMenu sysMenu) {
        sysMenuMapper.update(sysMenu);
    }

    /**
     * 根据id删除菜单
     * @param id 菜单id
     */
    @Override
    public void delete(Long id) {
        sysMenuMapper.delete(id);
    }

    /**
     * {
     *             "id": 1,
     *             "createTime": "2023-05-04 02:46:47",
     *             "updateTime": "2023-05-06 09:33:53",
     *             "isDeleted": 0,
     *             "parentId": 0,
     *             "title": "系统管理",
     *             "component": "system",
     *             "sortValue": 1,
     *             "status": 1,
     *             "children": [
     *                 {
     *                     "id": 2,
     *                     "createTime": "2023-05-04 02:47:13",
     *                     "updateTime": "2023-05-06 09:33:57",
     *                     "isDeleted": 0,
     *                     "parentId": 1,
     *                     "title": "用户管理",
     *                     "component": "sysUser",
     *                     "sortValue": 1,
     *                     "status": 1,
     *                     "children": []
     *                 }
     *            [
     * @param sysMenuList 构建好的树形菜单
     *
     */
    private List<SysMenuVo> buildMenuList(List<SysMenu> sysMenuList) {
        //创建List集合存储最终的数据
        List<SysMenuVo> sysMenuVoList = new LinkedList<>();
        //遍历sysMenuList 构建好的树形菜单
        sysMenuList.forEach(sysMenu -> {
            //创建菜单响应对象,封装数据
            SysMenuVo sysMenuVo = new SysMenuVo();
            //标题
            sysMenuVo.setTitle(sysMenu.getTitle());
            //Component组件名称
            sysMenuVo.setName(sysMenu.getComponent());
            //获取构建好的树形菜单里的Children数据
            List<SysMenu> children = sysMenu.getChildren();
            //判断children不为null
            if (!CollectionUtil.isEmpty(children)) {
                sysMenuVo.setChildren(buildMenuList(children));
            }
            //添加到List集合中
            sysMenuVoList.add(sysMenuVo);
        });
        return sysMenuVoList;
    }



}
